package com.itheima.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.common.CustomException;
import com.itheima.common.R;
import com.itheima.dto.DishDto;
import com.itheima.entity.*;
import com.itheima.service.CategoryService;
import com.itheima.service.DishFlavorService;
import com.itheima.service.DishService;
import com.itheima.utils.RedisConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RequestMapping("/dish")
@RestController
public class DishController {

    @Autowired
    private DishService dishService;
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 菜品信息分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    @Transactional
    public R pageQuery(int page,int pageSize,String name){
        Page<Dish> pageInfor=new Page<>(page,pageSize);
        LambdaQueryWrapper<Dish> lqw=new LambdaQueryWrapper<>();
        lqw.like(name!=null,Dish::getName,name).orderByAsc(Dish::getUpdateTime);
        dishService.page(pageInfor, lqw);
        List<Dish> records = pageInfor.getRecords();
        Long total=pageInfor.getTotal();
        Map map=new HashMap();
        map.put("total",total);
        //改变类型
        List<DishDto> dishDtos = records.stream().map(dish -> {
                    Long categoryId = dish.getCategoryId();
                    Category category = categoryService.getById(categoryId);
                    String categoryName = category.getName();
                    DishDto dishDto = new DishDto();
                    dishDto.setCategoryName(categoryName);
                    BeanUtils.copyProperties(dish, dishDto);//对象拷贝
                    return dishDto;
                }
        ).collect(Collectors.toList());
        map.put("records",dishDtos);
        return R.success(map);
    }

    /**
     * 新增菜品信息
     * @param dishDto
     * @return
     */
    @PostMapping
    @Transactional
    public R saveDish(@RequestBody DishDto dishDto){
        String key= RedisConstants.CACHE_DISH_KEY +dishDto.getCategoryId()+"_1";
        stringRedisTemplate.delete(key);
        dishService.save(dishDto);
       //判断是否选择风味
        List<DishFlavor> flavors = dishDto.getFlavors();
        if(flavors!=null&&flavors.size()>0){
            Long dishId = dishDto.getId();
            //存储风味dishflavor
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dishId);
                dishFlavorService.save(flavor);
            }
        }
        return R.success("新增成功");
    }

    /**
     * 需要修改的数据回显
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @Transactional
    public R  selectById(@PathVariable Long id){
        Dish dish = dishService.getById(id);
        Long dishId = dish.getId();
        LambdaQueryWrapper<DishFlavor> lqw=new LambdaQueryWrapper<>();
        lqw.eq(DishFlavor::getDishId,dishId);
        List<DishFlavor> dishFlavors = dishFlavorService.list(lqw);
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish,dishDto);
        dishDto.setFlavors(dishFlavors);
        return R.success(dishDto);
    }

    /**
     * 菜品信息修改
     * @param dishDto
     * @return
     */
    @PutMapping
    @Transactional
    public R updateDish(@RequestBody DishDto dishDto){

        log.info("dishDto:{}",dishDto.toString());
        //清楚缓存
        String key=RedisConstants.CACHE_DISH_KEY+dishDto.getCategoryId()+"_1";
        stringRedisTemplate.delete(key);
        //更新dish表
           dishService.updateById(dishDto);

           LambdaQueryWrapper<DishFlavor> lqw=new LambdaQueryWrapper<>();
           lqw.eq(DishFlavor::getDishId,dishDto.getId());
           dishFlavorService.remove(lqw);

            List<DishFlavor> flavors = dishDto.getFlavors().stream().map(item -> {
            item.setDishId(dishDto.getId());
            return item;
        }).collect(Collectors.toList());

        dishFlavorService.saveBatch(flavors);
        return R.success("修改成功");
    }

    @PostMapping("/status/{status}")
   public R<String> changeDishStatus(@PathVariable Integer status,Long[] ids ){
            //使用 LambdaUpdateWrapper 进行更新

        LambdaUpdateWrapper<Dish> luw = new LambdaUpdateWrapper<>();
        luw.set(Dish::getStatus,status).in(Dish::getId, ids);
         dishService.update(null,luw);
         return R.success("状态更改成功");
    }

    @DeleteMapping
    public R<String> deleDish(@RequestParam List<Long> ids){
        Set<String> keys = stringRedisTemplate.keys(RedisConstants.CACHE_DISH_KEY + "*");
        stringRedisTemplate.delete(keys);
        //先查询是否是停售状态
        LambdaQueryWrapper<Dish> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Dish::getStatus,0);
        lqw.in(Dish::getId,ids);
        int count =dishService.count(lqw);
        if(count>0){
            throw new CustomException("商品正在起售，禁止删除");
        }
        //1.删除dish表
        dishService.removeByIds(ids);
        //2.删除dishflavor表
        LambdaQueryWrapper<DishFlavor> lqws=new LambdaQueryWrapper<>();
        lqws.in(DishFlavor::getDishId,ids);
        dishFlavorService.remove(lqws);
        return R.success("删除成功");
    }

    /**
     * 查询dish列表
     * @param
     * @return
     */
    //先从缓存取数据，缓存中没有去数据库中查找，并将数据写入缓存
    @GetMapping("/list")
    public R getDishList(Dish dish){
        List<DishDto> dishDtos = null;
        String key=RedisConstants.CACHE_DISH_KEY+dish.getCategoryId()+"_"+
                dish.getStatus();
        String dishDtosJson=stringRedisTemplate.opsForValue().get(key);
        if(dishDtosJson!=null){
            dishDtos = JSON.parseArray(dishDtosJson, DishDto.class);
            return R.success(dishDtos);
        }
            LambdaQueryWrapper<Dish> lqw=new LambdaQueryWrapper<>();
            lqw.eq(dish.getCategoryId()!=null,Dish::getCategoryId, dish.getCategoryId());
            lqw.eq(dish.getStatus()!=null,Dish::getStatus,dish.getStatus());
            List<Dish> dishes = dishService.list(lqw);
             dishDtos = dishes.stream().map(dishs -> {
                LambdaQueryWrapper<DishFlavor> lqws = new LambdaQueryWrapper<>();
                lqws.eq(dishs.getId() != null, DishFlavor::getDishId, dishs.getId());
                List<DishFlavor> dishFlavors = dishFlavorService.list(lqws);
                DishDto dishDto = new DishDto();
                BeanUtils.copyProperties(dishs, dishDto);
                dishDto.setFlavors(dishFlavors);
                return dishDto;
            }).collect(Collectors.toList());
          stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(dishDtos),60, TimeUnit.SECONDS);
        return R.success(dishDtos);
    }


}
